package com.cskaoyan.service.wx_cart;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cskaoyan.bean.bo.wx_cart.CartAddBO;
import com.cskaoyan.bean.bo.wx_cart.CartCheckoutBO;
import com.cskaoyan.bean.bo.wx_cart.CartUpdateBO;
import com.cskaoyan.bean.po.ohter.MarketCart;
import com.cskaoyan.bean.po.ohter.MarketSystem;
import com.cskaoyan.bean.po.ohter.MarketSystemExample;
import com.cskaoyan.bean.po.promotionpo.MarketCouponUserExample;
import com.cskaoyan.bean.po.wx_cart.*;
import com.cskaoyan.bean.vo.wx_cart.CartCheckoutVO;
import com.cskaoyan.bean.vo.wx_cart.CartIndexVO;
import com.cskaoyan.mapper.MarketCartMapper;
import com.cskaoyan.mapper.MarketSystemMapper;
import com.cskaoyan.mapper.promotion.MarketCouponUserMapper;
import com.cskaoyan.mapper.wx_cart.*;
import com.cskaoyan.util.beanutils.BeanUtil;
import com.cskaoyan.util.common.Constant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: market
 * @description: 前台购物车实现类注册到容器
 * @author: zhong
 * @create: 2022-07-19 10:52
 **/
@Service
public class WxCartServiceImpl implements WxCartService {
    //逆向generator生成Mapper
    @Autowired
    MarketCouponUserMapper marketCouponUserMapper;
    @Autowired
    MarketSystemMapper marketSystemMapper;
    @Autowired
    MarketCartMapper marketCartMapper;//规格使用String
    //mybatisPlus Mapper
    @Autowired
    CartItemMapper cartItemMapper;//CartItemInfo规格使用String数组
    @Autowired
    CartAddressMapper cartAddressMapper;
    @Autowired
    CartCouponMapper cartCouponMapper;
    @Autowired
    CartGrouponMapper cartGrouponMapper;
    @Autowired
    CartProductMapper cartProductMapper;
    @Autowired
    CartGoodsMapper cartGoodsMapper;


    @Override
    public CartIndexVO listProductsOp(int userId) {
        List<CartItemInfo> cartItemInfos = new ArrayList<>();
        CartTotalInfo totalInfo = new CartTotalInfo();
        totalInfo.setGoodsAmount(new BigDecimal(0));
        totalInfo.setCheckedGoodsAmount(new BigDecimal(0));
        totalInfo.setGoodsCount(0);
        totalInfo.setCheckedGoodsCount(0);
        if (userId == -1) {
            return new CartIndexVO(cartItemInfos, totalInfo);
        }

        QueryWrapper<CartItemInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("`user_id`", userId);
        wrapper.eq("`deleted`", false);
        cartItemInfos = cartItemMapper.selectList(wrapper);
        if (cartItemInfos.size() == 0) {
            //System.out.println("购物车为空");
            return new CartIndexVO(cartItemInfos, totalInfo);
        }

        //购物车不空，count，amount不空
        Integer goodsCount = cartItemInfos
                .stream()
                .map(CartItemInfo::getNumber)
                .map(Short::intValue)
                .reduce((a, b) -> a + b)
                .get();
        totalInfo.setGoodsCount(goodsCount);

        BigDecimal goodsAmount = cartItemInfos
                .stream()
                .map(CartItemInfo::getPrice)
                .reduce(BigDecimal::add)
                .get();
        totalInfo.setGoodsAmount(goodsAmount);

        //checked可能空
        Optional<Integer> checkedCountOp = cartItemInfos
                .stream()
                .filter(item -> item.getChecked().equals(Boolean.TRUE))
                .map(CartItemInfo::getNumber)
                .map(Short::intValue)
                .reduce((a, b) -> a + b);
        long checkedCount;
        try {
            checkedCount = checkedCountOp.get();
        } catch (NoSuchElementException e) {
            //无确认购物车，checked空
            checkedCount = 0;
        }
        totalInfo.setCheckedGoodsCount((int) checkedCount);

        //checked空？0：getBigDecimal
        BigDecimal checkedGoodsAmount = (checkedCount == 0) ?
                (new BigDecimal(0)) : (cartItemInfos
                .stream()
                .filter(item -> item.getChecked().equals(Boolean.TRUE))
                .map(CartItemInfo::getPrice)
                .reduce(BigDecimal::add)
                .get()
        );
        totalInfo.setCheckedGoodsAmount(checkedGoodsAmount);

        return new CartIndexVO(cartItemInfos, totalInfo);
    }

    @Override
    public int countProductOp(int userId) {
        List<CartItemInfo> cartItemInfos;
        QueryWrapper<CartItemInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("`user_id`", userId);
        wrapper.eq("`deleted`", false);

        cartItemInfos = cartItemMapper.selectList(wrapper);
        if (cartItemInfos.size() == 0) {
            //System.out.println("购物车为空");
            return 0;
        }

        Integer goodsCount = cartItemInfos
                .stream()
                .map(CartItemInfo::getNumber)
                .map(Short::intValue)
                .reduce((a, b) -> a + b)
                .get();
        return goodsCount;
    }

    @Override
    public CartCheckoutVO listCheckoutInfoOp(CartCheckoutBO checkoutBO, int userId) {
        CartCheckoutVO checkoutInfo = new CartCheckoutVO();
        //cartId、addressId、couponId、userCouponId、grouponRulesId
        BeanUtil.copyBean(checkoutBO, checkoutInfo);

        //checkoutBO为0

        QueryWrapper<CartItemInfo> cartWrapper = new QueryWrapper<>();
        //查userId
        //cartWrapper.eq("`id`",checkoutBO.getCartId());
        //CartItemInfo one = cartItemMapper.selectOne(cartWrapper);
        //Integer userId = one.getUserId();

        //checkedGoodsList
        cartWrapper = new QueryWrapper<>();
        cartWrapper.eq("`user_id`", userId);
        cartWrapper.eq("`checked`", true);
        cartWrapper.eq("`deleted`", false);
        List<CartItemInfo> checkedGoodsList = cartItemMapper.selectList(cartWrapper);
        checkoutInfo.setCheckedGoodsList(checkedGoodsList);

        //checkedAddress
        QueryWrapper<CartAddressInfo> addressWrapper = new QueryWrapper<>();
        addressWrapper.eq("`id`", checkoutBO.getAddressId());
        CartAddressInfo checkedAddress = new CartAddressInfo();
        if (checkoutBO.getAddressId() != 0) {
            checkedAddress = cartAddressMapper.selectOne(addressWrapper);
        } else {
            checkedAddress.setId(0);
        }
        checkoutInfo.setCheckedAddress(checkedAddress);

        //优惠券张数
        MarketCouponUserExample couponExample = new MarketCouponUserExample();
        MarketCouponUserExample.Criteria couponReg = couponExample.createCriteria();
        couponReg.andUserIdEqualTo(userId);
        long countCoupon = marketCouponUserMapper.countByExample(couponExample);
        checkoutInfo.setAvailableCouponLength((int) countCoupon);

        //商品合计
        BigDecimal goodsTotalPrice = checkedGoodsList
                .stream()
                .filter(item -> item.getChecked().equals(Boolean.TRUE))
                .map(CartItemInfo::getPrice)
                .reduce(BigDecimal::add)
                .get();
        checkoutInfo.setGoodsTotalPrice(goodsTotalPrice);

        //运费
        MarketSystemExample systemExample = new MarketSystemExample();
        MarketSystemExample.Criteria systemReg = systemExample.createCriteria();
        systemReg.andKeyNameLike("market_express_freight%");
        systemReg.andDeletedEqualTo(false);
        Map<String, String> expressConf = marketSystemMapper
                .selectByExample(systemExample)
                .stream()
                .collect(Collectors.toMap(MarketSystem::getKeyName, MarketSystem::getKeyValue));
        BigDecimal minPriceForFreeFreight = new BigDecimal(expressConf.get("market_express_freight_min"));
        BigDecimal freight = new BigDecimal(expressConf.get("market_express_freight_value"));
        if (goodsTotalPrice.compareTo(minPriceForFreeFreight) > -1) {
            //goodsTotalPrice >= minPriceForFreeFreight,商品总价达到免运费最低价
            freight = BigDecimal.valueOf(0);
        }
        checkoutInfo.setFreightPrice(freight);

        // 优惠券折价,未选择优惠券，id-1，折价为0
        BigDecimal couponPrice = new BigDecimal(0);
        if (checkoutBO.getCouponId() != -1) {
            //选择优惠券
            QueryWrapper<CartCouponInfo> couponWrapper = new QueryWrapper<>();
            couponWrapper.eq("`id`", checkoutBO.getCouponId());
            try {
                CartCouponInfo cartCouponInfo = cartCouponMapper.selectOne(couponWrapper);
                couponPrice = cartCouponInfo.getDiscount();
            } catch (NullPointerException e) {
                //e.printStackTrace();
                System.out.println("数据库无优惠券记录");
            }
        }
        checkoutInfo.setCouponPrice(couponPrice);

        // 订单总价=商品合计+运费-优惠券折价
        BigDecimal orderTotalPrice = goodsTotalPrice.add(freight).subtract(couponPrice);
        checkoutInfo.setOrderTotalPrice(orderTotalPrice);

        // 团购折价,无团购优惠，id=0，折价为0
        BigDecimal grouponPrice = new BigDecimal(0);
        if (checkoutBO.getGrouponRulesId() != 0) {
            //确定团购折价
            QueryWrapper<CartGrouponInfo> grouponWrapper = new QueryWrapper<>();
            grouponWrapper.eq("`id`", checkoutBO.getGrouponRulesId());

            try {
                CartGrouponInfo cartGrouponInfo = cartGrouponMapper.selectOne(grouponWrapper);
                grouponPrice = cartGrouponInfo.getDiscount();
            } catch (NullPointerException e) {
                //e.printStackTrace();
                System.out.println("数据库无团购方案记录");
            }
        }
        checkoutInfo.setGrouponPrice(grouponPrice);

        // 实际付款=订单总价-团购折价
        BigDecimal actualPrice = orderTotalPrice.subtract(grouponPrice);
        checkoutInfo.setActualPrice(actualPrice);

        return checkoutInfo;
    }

    @Override
    public int updateCheckedOp(Map checkedInfo, int userId) {
        Boolean isChecked = ((Integer) checkedInfo.get("isChecked") == 1);
        List<Integer> productIds = (List<Integer>) checkedInfo.get("productIds");
        CartItemInfo entity = new CartItemInfo();
        entity.setChecked(isChecked);
        int updateRow = 0;
        for (Integer productId : productIds) {
            QueryWrapper<CartItemInfo> wrapper = new QueryWrapper<>();
            wrapper.eq("`user_id`", userId);
            wrapper.eq("`product_id`", productId);
            updateRow += cartItemMapper.update(entity, wrapper);
        }
        if (updateRow != productIds.size()) {
            return Constant.NOT_FOUND_CODE;
        }
        return Constant.OK_CODE;
    }

    @Override
    public CartResp addOp(CartAddBO cartAddBO, int userId) {
        QueryWrapper<CartProductInfo> productWrapper = new QueryWrapper<>();
        productWrapper.eq("`id`", cartAddBO.getProductId());
        CartProductInfo productInfo = cartProductMapper.selectOne(productWrapper);
        //库存不足时前端不会发送请求,但是也查一下，避免数据冲突,但不必更新库存
        if (productInfo == null ||productInfo.getNumber() < cartAddBO.getNumber()) {
            return new CartResp(Constant.FORBIDDEN_CODE, -1);
        }

        // 判断cart中是否已有userId、productId相同的记录，该记录是唯一的，已存在则更新
        QueryWrapper<CartItemInfo> cartWrapper = new QueryWrapper<>();
        cartWrapper.eq("`user_id`", userId);
        cartWrapper.eq("`product_id`", cartAddBO.getProductId());
        cartWrapper.eq("`deleted`", false);
        CartItemInfo cartItemInfos = cartItemMapper.selectOne(cartWrapper);

        int row;
        Integer cartId;
        if (cartItemInfos == null) {
            //无产品记录，插入购物车,不能用cartItemInfo赋值
            MarketCart addTarget = new MarketCart();
            addTarget.setAddTime(new Date());
            addTarget.setUpdateTime(addTarget.getAddTime());
            addTarget.setDeleted(false);
            addTarget.setChecked(true);

            addTarget.setNumber(cartAddBO.getNumber().shortValue());
            addTarget.setUserId(userId);
            addTarget.setGoodsId(cartAddBO.getGoodsId());
            addTarget.setProductId(cartAddBO.getProductId());

            //查询goods表
            QueryWrapper<CartGoodsInfo> goodsWrapper = new QueryWrapper<>();
            goodsWrapper.eq("`id`", cartAddBO.getGoodsId());
            CartGoodsInfo goodsInfo = cartGoodsMapper.selectOne(goodsWrapper);
            addTarget.setGoodsSn(goodsInfo.getGoodsSn());
            addTarget.setGoodsName(goodsInfo.getName());

            addTarget.setPrice(productInfo.getPrice());
            addTarget.setSpecifications(productInfo.getSpecifications());
            addTarget.setPicUrl(productInfo.getUrl());

            row = marketCartMapper.insert(addTarget);//全插入
            cartId = addTarget.getId();
        } else {
            //有记录，更新购物车
            MarketCart updateTarget = new MarketCart();
            //设置目标Id
            updateTarget.setId(cartItemInfos.getId());
            //更新时间
            updateTarget.setUpdateTime(new Date());
            //更新数量
            Short existedNumber = cartItemInfos.getNumber();
            int number = (existedNumber + cartAddBO.getNumber());
            updateTarget.setNumber((short) number);
            row = marketCartMapper.updateByPrimaryKeySelective(updateTarget);//选择性更新
            cartId = updateTarget.getId();
        }

        if (row == 0) {
            return new CartResp(Constant.UNAUTHORIZED_CODE, -1);
        } else {
            return new CartResp(Constant.OK_CODE, cartId);
        }
    }

    @Override
    public int updateProductNumOp(CartUpdateBO updateInfo) {
        //查库存
        QueryWrapper<CartProductInfo> productWrapper = new QueryWrapper<>();
        productWrapper.eq("`id`", updateInfo.getProductId());
        CartProductInfo productInfo = cartProductMapper.selectOne(productWrapper);
        if (productInfo == null || productInfo.getNumber() < updateInfo.getNumber()) {
            //无产品信息或库存不足
            return Constant.FORBIDDEN_CODE;
        }
        MarketCart updateTarget = new MarketCart();
        updateTarget.setId(updateInfo.getId());
        updateTarget.setNumber(updateInfo.getNumber().shortValue());
        updateTarget.setUpdateTime(new Date());

        int updateRow = marketCartMapper.updateByPrimaryKeySelective(updateTarget);
        if (updateRow == 0) {
            return Constant.NOT_FOUND_CODE;
        }
        return Constant.OK_CODE;
    }

    @Override
    public int delCartOp(List<Integer> productIds, int userId) {
        QueryWrapper<CartItemInfo> cartWrapper = new QueryWrapper<>();
        cartWrapper.eq("`user_id`",userId);
        cartWrapper.in("`product_id`", productIds);
        CartItemInfo entity = new CartItemInfo();
        entity.setDeleted(true);
        int updateRow = cartItemMapper.update(entity, cartWrapper);
        if (updateRow == 0) {
            return Constant.NOT_FOUND_CODE;
        }
        return Constant.OK_CODE;
    }


}
